config: fix memleak during odhcpd reload
authorFei Lv <[email protected]>
Fri, 14 Nov 2025 07:31:22 +0000 (15:31 +0800)
committerÁlvaro Fernández Rojas <[email protected]>
Fri, 14 Nov 2025 16:27:45 +0000 (17:27 +0100)
- The memset in close_interface reset the pios pointer before it
  could be freed, causing a memory leak. Relocate the free call
  to clean_interface to ensure proper deallocation.

- Use realloc instead of malloc in config_load_ra_pio()
  This function may be called multiple times during odhcpd reload,
  and using malloc without freeing the previous allocation was
  causing memory leaks.

Signed-off-by: Fei Lv <[email protected]>
Link: https://github.com/openwrt/odhcpd/pull/309
Signed-off-by: Álvaro Fernández Rojas <[email protected]>
src/config.c

index 598b1e8f6aafc720f1cd9d5bb4f5acfbc46acb9d..ff93da71b6fd321bf08d4dc61133e8beb4ae1c74 100644 (file)
@@ -352,6 +352,7 @@ static void clean_interface(struct interface *iface)
                free(iface->dnr[i].svc);
        }
        free(iface->dnr);
+       free(iface->pios);
        memset(&iface->ra, 0, sizeof(*iface) - offsetof(struct interface, ra));
        set_interface_defaults(iface);
 }
@@ -373,7 +374,6 @@ static void close_interface(struct interface *iface)
        clean_interface(iface);
        free(iface->addr4);
        free(iface->addr6);
-       free(iface->pios);
        free(iface->ifname);
        free(iface);
 }
@@ -2019,6 +2019,7 @@ static json_object *config_load_ra_pio_json(struct interface *iface)
 void config_load_ra_pio(struct interface *iface)
 {
        json_object *json, *slaac_json;
+       struct ra_pio *new_pios;
        size_t pio_cnt;
        time_t now;
 
@@ -2038,12 +2039,13 @@ void config_load_ra_pio(struct interface *iface)
        now = odhcpd_time();
 
        pio_cnt = json_object_array_length(slaac_json);
-       iface->pios = malloc(sizeof(struct ra_pio) * pio_cnt);
-       if (!iface->pios) {
+       new_pios = realloc(iface->pios, sizeof(struct ra_pio) * pio_cnt);
+       if (!new_pios) {
                json_object_put(json);
                return;
        }
 
+       iface->pios = new_pios;
        iface->pio_cnt = 0;
        for (size_t i = 0; i < pio_cnt; i++) {
                json_object *cur_pio_json, *length_json, *prefix_json;